home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / ODF Release 3 / ODFDev / Draw / Sources / DrwDDCmd.cpp < prev    next >
Encoding:
Text File  |  1996-12-16  |  16.7 KB  |  521 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                DrwDDCmd.cpp
  4. //    Release Version:    $ ODF 3 $
  5. //
  6. //    Author:                Mary Boetcher
  7. //
  8. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9. //
  10. //========================================================================================
  11.  
  12. #include "ODFDraw.hpp"
  13.  
  14. #ifndef DRWDDCMD_H
  15. #include "DrwDDCmd.h"
  16. #endif
  17.  
  18. #ifndef DRAWCONT_H
  19. #include "DrawCont.h"
  20. #endif
  21.  
  22. #ifndef DRAWSEL_H
  23. #include "DrawSel.h"
  24. #endif
  25.  
  26. #ifndef BASESHP_H
  27. #include "BaseShp.h"
  28. #endif
  29.  
  30. #ifndef DRAWPART_H
  31. #include "DrawPart.h"
  32. #endif
  33.  
  34. #ifndef DRAWCLIP_H
  35. #include "DrawClip.h"
  36. #endif
  37.  
  38. #ifndef DRAWLINK_H
  39. #include "DrawLink.h"
  40. #endif
  41.  
  42. // ----- FrameWork Includes -----
  43.  
  44. #ifndef FWFRAME_H
  45. #include "FWFrame.h"
  46. #endif
  47.  
  48. #ifndef FWPRESEN_H
  49. #include "FWPresen.h"
  50. #endif
  51.  
  52. #ifndef FWSESION_H
  53. #include "FWSesion.h"
  54. #endif
  55.  
  56. //========================================================================================
  57. // RunTime Info
  58. //========================================================================================
  59.  
  60. #ifdef FW_BUILD_MAC
  61. #pragma segment odfdrawcommand
  62. #endif
  63.  
  64. FW_DEFINE_AUTO(CDrawDragCommand)
  65. FW_DEFINE_AUTO(CDrawDropCommand)
  66.  
  67. //========================================================================================
  68. // class CDrawDragCommand
  69. //========================================================================================
  70.  
  71. //----------------------------------------------------------------------------------------
  72. //    CDrawDragCommand constructor
  73. //----------------------------------------------------------------------------------------
  74. CDrawDragCommand::CDrawDragCommand(Environment* ev,
  75.                                    CDrawPart* part,
  76.                                    FW_CFrame* frame,
  77.                                    CDrawSelection* selection,
  78.                                    FW_Boolean canUndo)
  79.     : FW_CDragCommand(ev, frame, canUndo),
  80.         fDrawPart(part),
  81.         fDrawSelection(selection),
  82.         fDraggedContent(NULL),
  83.         fLinkSources(NULL)
  84. {
  85.     FW_END_CONSTRUCTOR
  86. }
  87.  
  88. //----------------------------------------------------------------------------------------
  89. //    CDrawDragCommand destructor
  90. //----------------------------------------------------------------------------------------
  91.  
  92. CDrawDragCommand::~CDrawDragCommand()
  93. {
  94.     FW_START_DESTRUCTOR
  95.     delete fDraggedContent;        // Will call remove all if necessary
  96.     fDraggedContent = NULL;
  97.     
  98.     delete fLinkSources;
  99.     fLinkSources = NULL;
  100. }
  101.  
  102. //----------------------------------------------------------------------------------------
  103. //    CDrawDragCommand::SaveUndoState
  104. //----------------------------------------------------------------------------------------
  105.  
  106. void CDrawDragCommand::SaveUndoState(Environment* ev)    // Override
  107. {
  108.     FW_ASSERT(fDraggedContent == NULL);    
  109.     fDraggedContent = FW_NEW(CDrawUndoContent, (ev, fDrawPart, fDrawSelection));
  110.     
  111.     fLinkSources = fDrawSelection->GetSelectedLinkSources();
  112. }
  113.  
  114. //----------------------------------------------------------------------------------------
  115. //    CDrawDragCommand::UndoIt
  116. //----------------------------------------------------------------------------------------
  117.  
  118. void CDrawDragCommand::UndoIt(Environment* ev)    // Override
  119. {
  120.     // ----- Add the dragged shapes back into the part
  121.     CDrawContentShapeIterator ite(fDraggedContent);
  122.     for (CBaseShape* shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  123.     {
  124.         shape->RestoreShape(ev);
  125.     }
  126.  
  127.     fDraggedContent->RestoreLinks(ev);
  128.     
  129.     // ----- Add the saved shapes to the selection
  130.     fDrawSelection->SelectContent(ev, fDraggedContent);
  131.     
  132.     // ----- Invalidate 
  133.     GetPresentation(ev)->Invalidate(ev, fDrawSelection->GetUpdateShape());
  134. }
  135.  
  136. //----------------------------------------------------------------------------------------
  137. //    CDrawDragCommand::RedoIt
  138. //----------------------------------------------------------------------------------------
  139.  
  140. void CDrawDragCommand::RedoIt(Environment* ev)    // Override
  141. {
  142.     // Select saved shapes
  143.     fDrawSelection->SelectContent(ev, fDraggedContent);
  144.  
  145.     fDrawSelection->ClearSelection(ev); // clear them, again
  146.     
  147.     fDraggedContent->RemoveFromLinks(ev);
  148. }
  149.  
  150. //----------------------------------------------------------------------------------------
  151. //    CDrawDragCommand::FreeUndoState
  152. //----------------------------------------------------------------------------------------
  153.  
  154. void CDrawDragCommand::FreeUndoState(Environment *ev)    // Override
  155. {
  156.     // Delete link sources left empty because all their shapes were removed
  157.     fDraggedContent->DeleteEmptyLinkSources(ev);
  158.  
  159.     // Delete undo data
  160.     fDraggedContent->DeleteSavedLinks(ev);
  161. }
  162.  
  163. //----------------------------------------------------------------------------------------
  164. //    CDrawDragCommand::PropagateChanges
  165. //----------------------------------------------------------------------------------------
  166.  
  167. void  CDrawDragCommand::PropagateChanges(Environment* ev,  ODUpdateID id )
  168. {
  169.     // Propagate changes should only be called when content was removed from the part.
  170.     FW_ASSERT(IsDragMoveToAnotherPart);
  171.     
  172.     if (fLinkSources)
  173.     {
  174.         //--- Update affected links ---
  175.         id = FW_CSession::UniqueUpdateID(ev);
  176.         CDrawPublishLinkCollectionIterator iter(fLinkSources);
  177.         for (CDrawPublishLink* link = iter.First(); iter.IsNotComplete(); link = iter.Next())
  178.         {
  179.             link->ContentUpdated(ev, id);
  180.         }
  181.     }
  182.     
  183.     FW_CDragCommand::PropagateChanges(ev, id);
  184. }
  185.  
  186. //----------------------------------------------------------------------------------------
  187. //    CDrawDragCommand::DoIt
  188. //----------------------------------------------------------------------------------------
  189.  
  190. void  CDrawDragCommand::DoIt(Environment* ev)
  191. {
  192.     FW_CDragCommand::DoIt(ev);
  193.     
  194.     if (fDraggedContent)
  195.         fDraggedContent->RemoveFromLinks(ev);
  196. }
  197.  
  198. //========================================================================================
  199. // class CDrawDropCommand
  200. //========================================================================================
  201.  
  202. //----------------------------------------------------------------------------------------
  203. //    CDrawDropCommand constructor
  204. //----------------------------------------------------------------------------------------
  205. CDrawDropCommand::CDrawDropCommand(Environment* ev,
  206.                                    CDrawPart* part,
  207.                                    FW_CFrame* frame,
  208.                                    ODDragItemIterator* dropInfo, 
  209.                                    ODFacet* facet, 
  210.                                    const FW_CPoint& windowPoint,
  211.                                    FW_Boolean canUndo)
  212.     : FW_CDropCommand(ev, frame, dropInfo, facet, windowPoint, canUndo),
  213.         fDrawPart(part),
  214.         fSavedLink(NULL),
  215.         fDropDelta(FW_kZeroPoint),
  216.         fDroppedContent(NULL),
  217.         fSavedSelection(NULL),
  218.         fDrawSelection((CDrawSelection*)GetPresentation(ev)->GetSelection(ev))
  219. {
  220.     FW_END_CONSTRUCTOR
  221. }
  222.  
  223. //----------------------------------------------------------------------------------------
  224. //    CDrawDropCommand destructor
  225. //----------------------------------------------------------------------------------------
  226.  
  227. CDrawDropCommand::~CDrawDropCommand()
  228. {
  229.     FW_START_DESTRUCTOR
  230.     delete fDroppedContent;
  231.     delete fSavedSelection;
  232. }
  233.  
  234. //----------------------------------------------------------------------------------------
  235. //    CDrawDropCommand::DoDrop
  236. //----------------------------------------------------------------------------------------
  237. FW_Boolean CDrawDropCommand::DoDrop(Environment* ev, 
  238.                                 ODStorageUnit* dropSU, 
  239.                                 const FW_CPoint& mouseDownOffset, 
  240.                                 const FW_CPoint& dropPoint,
  241.                                 FW_Boolean isDropMove,
  242.                                 short itemNumber)
  243. {
  244.     FW_ASSERT(fDrawSelection->IsEmpty(ev));
  245.     
  246.     FW_Boolean result = FW_CDropCommand::DoDrop(ev, dropSU, mouseDownOffset, dropPoint, isDropMove, itemNumber);
  247.     
  248.     if (result)
  249.     {    
  250.         fDrawPart->SetTool(ev, kSelectTool);
  251.         
  252.         fDrawSelection->CalcCache(ev);
  253.         
  254.         FW_CPoint newPosition(dropPoint.x - mouseDownOffset.x, dropPoint.y - mouseDownOffset.y);
  255.         
  256.         FW_CRect box = fDrawSelection->GetDragRect();
  257.  
  258.         fDrawSelection->OffsetSelection(ev, newPosition.x - box.left, newPosition.y - box.top);
  259.         
  260.         ODShape* updateShape = fDrawSelection->GetUpdateShape();
  261.         
  262.         // ----- Calculate clip -----
  263.         CDrawFacetClipper facetClipper(fDrawPart);
  264.         facetClipper.Clip(ev, fDrawSelection->GetPresentation(ev), updateShape);    
  265.  
  266.         // ----- Invalidate -----
  267.         GetPresentation(ev)->Invalidate(ev, updateShape);
  268.         
  269.         // ----- If I am not the active part I should not have a selection -----
  270.         if (!fDrawPart->HasSelectionFocus(ev))
  271.             fDrawSelection->CloseSelection(ev);
  272.     }
  273.     
  274.     return result;
  275. }
  276.  
  277. //----------------------------------------------------------------------------------------
  278. //    CDrawDropCommand::DoDroppedInSameFrame
  279. //----------------------------------------------------------------------------------------
  280.  
  281. FW_Boolean CDrawDropCommand::DoDroppedInSameFrame(Environment* ev, 
  282.                                               ODStorageUnit* dropSU, 
  283.                                               const FW_CPoint& mouseDownOffset, 
  284.                                               const FW_CPoint& dropPoint)
  285. {
  286.     FW_UNUSED(dropSU);
  287.     
  288.     // Restore the selection which we had to close in case HandlePasteAs would interalize  into it.
  289.     FW_ASSERT(fDrawSelection->IsEmpty(ev));
  290.     fDrawSelection->SelectContent(ev, fSavedSelection);
  291.  
  292.     
  293.     FW_CPoint newPosition(dropPoint.x - mouseDownOffset.x, dropPoint.y - mouseDownOffset.y);
  294.  
  295.     FW_CRect box = fDrawSelection->GetDragRect();
  296.  
  297.     fDropDelta.Set(newPosition.x - box.left, newPosition.y - box.top);
  298.     
  299.     this->OffsetSelection(ev, fDropDelta);
  300.  
  301.     return TRUE;
  302. }
  303.  
  304. //----------------------------------------------------------------------------------------
  305. //    CDrawDropCommand::SaveRedoState
  306. //----------------------------------------------------------------------------------------
  307.  
  308. void CDrawDropCommand::SaveRedoState(Environment* ev)    // Override
  309. {
  310.     if (fSavedLink == NULL)    // if a link was created, don't need to save anything
  311.     {
  312.         // Save shapes that were just dropped
  313.         FW_ASSERT(fDroppedContent == NULL);
  314.         fDroppedContent = FW_NEW(CDrawUndoContent, (ev, fDrawPart, fDrawSelection));
  315.     }
  316. }
  317.  
  318. //----------------------------------------------------------------------------------------
  319. //    CDrawDropCommand::UndoIt
  320. //----------------------------------------------------------------------------------------
  321. void CDrawDropCommand::UndoIt(Environment* ev)    // Override
  322. {
  323.     if (fSavedLink)
  324.     {
  325.         fSavedLink->SelectShapes(ev);            // set the selection's update shape
  326.         GetDrawLinkManager(ev)->UndoPasteAs(ev, fSavedLink);
  327.         GetPresentation(ev)->Invalidate(ev, fDrawSelection->GetUpdateShape());
  328.     }
  329.     else if (this->IsDragMoveInSameFrame(ev))    // it's a drag-move
  330.     {
  331.         // select dropped shapes and move them back to the original position
  332.         fDrawSelection->SelectContent(ev, fDroppedContent);
  333.         this->OffsetSelection(ev, -fDropDelta);
  334.     }
  335.     else
  336.     {
  337.         // select dropped shapes and remove them from the document
  338.         fDrawSelection->SelectContent(ev, fDroppedContent);
  339.         fDrawSelection->ClearSelection(ev);
  340.     }
  341. }
  342.  
  343. //----------------------------------------------------------------------------------------
  344. //    CDrawDropCommand::RedoIt
  345. //----------------------------------------------------------------------------------------
  346. void CDrawDropCommand::RedoIt(Environment* ev)    // Override
  347. {
  348.     if (fSavedLink)
  349.     {
  350.         GetDrawLinkManager(ev)->RedoPasteAs(ev, fSavedLink);
  351.         fSavedLink->SelectShapes(ev);
  352.         GetPresentation(ev)->Invalidate(ev, fDrawSelection->GetUpdateShape());
  353.     }
  354.     else if (this->IsDragMoveInSameFrame(ev))    // it's a drag-move
  355.     {
  356.         // select dropped shapes and move them to new position
  357.         fDrawSelection->SelectContent(ev, fDroppedContent);
  358.         this->OffsetSelection(ev, fDropDelta);
  359.     }
  360.     else    // dropped shapes are copies
  361.     {
  362.         // add dropped shapes back into document
  363.         this->RestoreDroppedShapes(ev);
  364.         GetPresentation(ev)->Invalidate(ev, fDrawSelection->GetUpdateShape());
  365.     }
  366. }
  367.  
  368. //----------------------------------------------------------------------------------------
  369. //    CDrawDropCommand::RestoreDroppedShapes
  370. //----------------------------------------------------------------------------------------
  371. void CDrawDropCommand::RestoreDroppedShapes(Environment* ev)
  372. {
  373.     // Add the dropped shapes back into the part
  374.     CDrawContentShapeIterator ite(fDroppedContent);
  375.     for (CBaseShape* shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  376.     {
  377.         shape->RestoreShape(ev);
  378.     }
  379.  
  380.     // Add the saved shapes to the selection
  381.     fDrawSelection->SelectContent(ev, fDroppedContent);
  382. }
  383.  
  384. //----------------------------------------------------------------------------------------
  385. //    CDrawDropCommand::OffsetSelection
  386. //----------------------------------------------------------------------------------------
  387.  
  388. void CDrawDropCommand::OffsetSelection(Environment* ev, const FW_CPoint& delta)
  389. {
  390.     if (delta != FW_kZeroPoint)
  391.     {
  392.         GetPresentation(ev)->Invalidate(ev, fDrawSelection->GetUpdateShape());
  393.         fDrawSelection->OffsetSelection(ev, delta.x, delta.y);
  394.         GetPresentation(ev)->Invalidate(ev, fDrawSelection->GetUpdateShape());
  395.  
  396.         // Adjust offsets of linked shapes
  397.         CDrawContentShapeIterator it(fDrawSelection->GetDrawContent(ev));
  398.         for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  399.         {
  400.             if (shape->GetSubscribeLink() != NULL)
  401.             {
  402.                 shape->GetSubscribeLink()->AdjustUpdateOffset(ev, delta);
  403.             }
  404.         }
  405.     }
  406. }
  407.  
  408. //----------------------------------------------------------------------------------------
  409. //    CDrawDropCommand::FreeRedoState
  410. //----------------------------------------------------------------------------------------
  411.  
  412. void CDrawDropCommand::FreeUndoState(Environment* ev)    // Override
  413. {
  414.     if (fSavedLink == NULL && fDroppedContent != NULL) 
  415.     {
  416.         fDroppedContent->CommitPasteDone(ev);
  417.     }
  418. }
  419.  
  420. //----------------------------------------------------------------------------------------
  421. //    CDrawDropCommand::GetDrawLinkManager
  422. //----------------------------------------------------------------------------------------
  423.  
  424. CDrawLinkManager* CDrawDropCommand::GetDrawLinkManager(Environment* ev) const
  425. {
  426.     return (CDrawLinkManager*) fDrawPart->GetLinkManager(ev);
  427. }
  428.  
  429. //----------------------------------------------------------------------------------------
  430. //    CDrawDropCommand::DoDroppedPasteAs
  431. //----------------------------------------------------------------------------------------
  432.  
  433. void CDrawDropCommand::DoDroppedPasteAs(Environment* ev, 
  434.                                     const FW_CPoint& mouseDownOffset, 
  435.                                     const FW_CPoint& dropPoint)
  436. {
  437.     FW_CPoint newPosition(dropPoint.x - mouseDownOffset.x, dropPoint.y - mouseDownOffset.y);
  438.     fDrawSelection->CalcCache(ev);
  439.     FW_CRect box = fDrawSelection->GetDragRect();
  440.     fDropDelta.Set(newPosition.x - box.left, newPosition.y - box.top);
  441.  
  442.     fSavedLink = (CDrawSubscribeLink*) this->GetNewLink(ev);
  443.  
  444.     if (fSavedLink)
  445.     {
  446.         if (!fSavedLink->IsEstablished(ev))    // cross-doc link not yet established
  447.             fDropDelta = FW_kZeroPoint;        // puts linked shapes in same position as original
  448.  
  449.         // ----- Save information about newly-created link
  450.         fSavedLink->SetUpdateOffset(ev, fDropDelta);
  451.     
  452.         if (fDropDelta != FW_kZeroPoint)
  453.         {
  454.             // invalidate and clear the current selection
  455.             GetPresentation(ev)->Invalidate(ev, fDrawSelection->GetUpdateShape());
  456.             fDrawSelection->CloseSelection(ev);    // empty the selection
  457.     
  458.             // Select the newly-subscribed shapes
  459.             fSavedLink->SelectShapes(ev);
  460.     
  461.             // offset the dropped shapes
  462.             fDrawSelection->OffsetSelection(ev, fDropDelta.x, fDropDelta.y);
  463.             GetPresentation(ev)->Invalidate(ev, fDrawSelection->GetUpdateShape());
  464.         }
  465.     }
  466.     else    // no link created - must be Embed As
  467.     {
  468.         fDrawPart->SetTool(ev, kSelectTool);
  469.         
  470.         fDrawSelection->OffsetSelection(ev, fDropDelta.x, fDropDelta.y);
  471.         ODShape* updateShape = fDrawSelection->GetUpdateShape();
  472.         
  473.         // ----- Calculate clip -----
  474.         CDrawFacetClipper facetClipper(fDrawPart);
  475.         facetClipper.Clip(ev, fDrawSelection->GetPresentation(ev), updateShape);    
  476.  
  477.         // ----- Invalidate -----
  478.         GetPresentation(ev)->Invalidate(ev, updateShape);
  479.     }
  480. }
  481.  
  482. //----------------------------------------------------------------------------------------
  483. //    CDrawDropCommand::PropagateChanges
  484. //----------------------------------------------------------------------------------------
  485.  
  486. void CDrawDropCommand::PropagateChanges(Environment* ev, ODUpdateID id )
  487. {
  488.  
  489.     if (this->IsDragMoveInSameFrame(ev))
  490.     {
  491.         if (id == kODUnknownUpdate)
  492.             id = FW_CSession::UniqueUpdateID(ev);
  493.             
  494.         fDrawSelection->SelectionChanged(ev, id);
  495.     }
  496.  
  497.     FW_CDropCommand::PropagateChanges(ev, id);
  498. }
  499.  
  500. //----------------------------------------------------------------------------------------
  501. //    CDrawDropCommand::SaveUndoState
  502. //----------------------------------------------------------------------------------------
  503.  
  504. void  CDrawDropCommand::SaveUndoState(Environment* ev)
  505. {
  506.     // There's no  'undo state' to save.  This is a workaround to a present shortcoming in the framework design:
  507.     // We need to close the selection before the framework possibly calls HandleDropPasteAsDialog, because
  508.     // that may attempt to interalize into the selection object.  But we also may be asked to 
  509.     // DropMoveInSameFrame, which requires the selection to be intact.  We will work around this until
  510.     // There's time to make the framework smarter, by taking a snapshot of the selection here before
  511.     // closing it, and restoring the selection from that in DropMoveInSameFrame, if and when that is called.
  512.     
  513.     fSavedSelection = FW_NEW(CDrawContent, (ev, fDrawPart, fDrawSelection->GetDrawContent(ev)));
  514.     fDrawSelection->CloseSelection(ev);
  515. }
  516.  
  517.  
  518.  
  519.  
  520.  
  521.